/*
 * Copyright 2006 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.user.rebind;

import com.google.gwt.core.ext.GeneratorContext;

import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Set;

public class ClassSourceFileComposerFactory {

  private String fCreatedPackage;
  private String fCreatedClassShortName;

  private String fSuperclassName;
  private Set fInterfaceNames = new HashSet();
  private Set fImports = new HashSet();

  public ClassSourceFileComposerFactory(String createdPackage,
      String createdClassShortName) {
    fCreatedPackage = createdPackage;
    fCreatedClassShortName = createdClassShortName;
  }

  /**
   * Creates an implementation of {@link SourceWriter} that can be used to write
   * the innards of a class. Note that the subsequent changes to this factory do
   * not affect the returned instance.
   * 
   * @throws RuntimeException If the settings on this factory are inconsistent
   *           or invalid
   */
  public SourceWriter createSourceWriter(GeneratorContext ctx, PrintWriter printWriter) {
    return new ClassSourceFileComposer(ctx, printWriter, getCreatedPackage(),
      getCreatedClassShortName(), getSuperclassName(), getInterfaceNames(),
      getImports());
  }
  
  public String[] getInterfaceNames() {
    return (String[]) fInterfaceNames
      .toArray(new String[fInterfaceNames.size()]);
  }

  private String[] getImports() {
    return (String[]) fImports
      .toArray(new String[fImports.size()]);
  }

  public String getSuperclassName() {
    return fSuperclassName;
  }

  public String getCreatedClassShortName() {
    return fCreatedClassShortName;
  }

  public String getCreatedPackage() {
    return fCreatedPackage;
  }

  public String getCreatedClassName() {
    return getCreatedPackage() + "." + getCreatedClassShortName();
  }

  public void addImplementedInterface(String intfName) {
    fInterfaceNames.add(intfName);
  }

  public void addImplementedInterface(Class intf) {
    addImplementedInterface(makeSourceCompatibleName(intf));
  }

  public void addImport(String typeName) {
    fImports.add(typeName);
  }

  public void addImport(Class type) {
    addImport(makeSourceCompatibleName(type));
  }

  public void setSuperclass(Class superclass) {
    setSuperclass(makeSourceCompatibleName(superclass));
  }

  public void setSuperclass(String superclassName) {
    fSuperclassName = superclassName;
  }

  private String makeSourceCompatibleName(Class c) {
    if (c.isArray())
      return makeSourceCompatibleName(c.getComponentType()) + "[]";
    else if (c.isPrimitive())
      return c.getName();
    else
      return c.getName().replace('$', '.');
  }
}
